// // 1、原型链继承
// // function SuperType() {
// //     this.colors = ['red', 'blue', 'green'];
// // }

// // function SubType() { }
// // SubType.prototype = new SuperType();

// // let instance1 = new SubType();
// // instance1.colors.push('black');
// // console.log(instance1.colors);

// // let instance2 = new SubType();
// // console.log(instance2.colors);

// // 2、借用构造函数继承, 
// // 在执行Child构造函数的时候，子类的实例各自得到一份构造函数的副本，
// // 属于值传递，所以子类之间的属性修改是互不相关的；
// // 缺点：单独使用无法达到函数复用，因为每一个函数和属性都需要在构造函数中定义，没法复用，
// // 即没有父类prototype上的函数，只有不能共用的实例属性
// // 而且instanceof操作无法确定子类实例和父类之间的关系，因为子类的prototype和父类无关
// function Parent() {
//     this.colors = ['red', 'blue', 'green'];
// }

// function Child() {
//     Parent.call(this);
// }

// let instance3 = new Child();
// instance3.colors.push('white');
// console.log(instance3.colors);

// let instance4 = new Child();
// console.log(instance4.colors);

// // 3、组合继承
// function Parent(name) {
//     this.name = [name]
// }
// Parent.prototype.getName = function () {
//     return this.name
// }
// function Child() {
//     // 构造函数继承
//     Parent.call(this, 'zhangsan')
// }
// //原型链继承
// Child.prototype = new Parent()
// Child.prototype.constructor = Child

// //测试
// const child1 = new Child()
// const child2 = new Child()
// child1.name[0] = 'foo'
// console.log(child1.name)          // ['foo']
// console.log(child2.name)          // ['zhangsan']
// child2.getName()                  // ['zhangsan']


// // 寄生组合式继承
// function Parent(name) {
//     this.name = [name]
// }
// Parent.prototype.getName = function () {
//     return this.name
// }
// function Child() {
//     // 构造函数继承
//     Parent.call(this, 'zhangsan')
// }
// //原型链继承
// // Child.prototype = new Parent()
// // Child.prototype = Parent.prototype  //将`指向父类实例`改为`指向父类原型`
// // 或如下：
// Child.prototype = Object.create(Parent.prototype, {
//     constructor: {
//         value: Child,
//         enumerable: false,
//         writable: true,
//         configurable: true
//     }
// })
// Child.prototype.constructor = Child

// //测试
// const child1 = new Child()
// const child2 = new Child()
// child1.name[0] = 'foo'
// console.log(child1.name)          // ['foo']
// console.log(child2.name)          // ['zhangsan']
// child2.getName()                  // ['zhangsan']


function Animal(legs) {
    this.legs = legs;
}

Animal.prototype.walk = function () {
    console.log(`Use ${this.legs} legs to walk!`);
};

function Cat(legs, eyes) {
    this.legs = legs;
    this.eyes = eyes;

    Animal.call(this, legs);
}
Cat.prototype.see = function () {
    console.log(`Use ${this.eyes} legs to walk!`);
}
// Child.prototype = new Parent()
// Child.prototype.constructor = Child
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat = new Cat(4, 2);

cat.walk(); // => Use 4 legs to walk!
cat.see(); // => Use 2 eyes to see!